<template>
  <div class="app-container">
    <qm-table
      ref="qmTable"
      keyProp="menuId"
      :data="{ data: menuData }"
      :showOrder="false"
      :showPager="false"
      menuType="text"
      :menuOptions="{ width: 180 }"
      :formOptions="{ labelWidth: '120px' }"
      :options="{
        rowId: 'menuId',
        border: false,
        treeConfig: { trigger: 'cell', reserve: true },
      }"
      :rules="rules"
      :showView="false"
      :showCheckbox="false"
      refreshType="none"
      :refreshFunc="treeRefresh"
      :removeFunc="removeRow"
      :textMap="{ add: '添加资源' }"
    >
      <qm-table-column field="text" tree-node>
        资源名称
        <template v-slot:content="{ row }">
          <span>
            <template v-if="row.children">
              <i
                class="tree-node-icon fa"
                :class="
                  $refs.qmTable.isTreeExpandByRow(row)
                    ? 'fa-folder-open-o'
                    : 'fa-folder-o'
                "
              ></i>
            </template>
            <template v-else>
              <i class="tree-node-icon fa fa-file-o"></i>
            </template>
            <span>{{ row.text }}</span>
          </span>
        </template>
      </qm-table-column>
      <qm-table-column field="type" width="120px">资源类型</qm-table-column>
      <qm-table-column field="code" width="200px">编码</qm-table-column>
      <!-- <qm-table-column field="route" width="200px">路由</qm-table-column> -->
      <qm-table-column field="navigateUrl" show-overflow>页面</qm-table-column>
      <qm-table-column field="isEnabled" width="120px" fieldtype="enabledisable"
        >是否启用</qm-table-column
      >

      <template v-slot:moreBtn="{ row }">
        <el-dropdown>
          <el-button style="padding-left: 7px;" size="mini" type="text">更多</el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item v-if="row.menuId"  v-hasPermi="['admin:sysMenu:add']" @click.native="addSubMenu(row)">添加资源</el-dropdown-item>
            <el-dropdown-item v-if="row.menuId"  v-hasPermi="['admin:sysMenu:add']" @click.native="setRoles(row)">分配角色</el-dropdown-item>
          </el-dropdown-menu>
        </el-dropdown>
      </template>

      <template v-slot:form="{ model, controlData }">
        <el-row>
          <el-col :span="24">
            <el-form-item label="上级菜单：" prop="model.parentId">
              <treeselect
                v-model="model.parentId"
                :options="menuData"
                :normalizer="normalizer"
                :show-count="true"
                placeholder="选择上级菜单"
                noChildrenText="没有了"
              />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="资源类型：" prop="model.category">
              <el-select v-model="model.category">
                <el-option
                  v-for="item in controlData.categoryOptions"
                  :key="item.value"
                  :label="item.key"
                  :value="item.value"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="编码：" prop="model.code">
              <el-input
                v-model="model.code"
                placeholder="页面按钮必填，格式：xxx:yyy:zzz；页面编码为路由"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="资源名称：" prop="model.name">
              <el-input v-model="model.name"></el-input>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="排序号：" prop="model.sort">
              <el-input
                v-model="model.sort"
                placeholder="(用于数据权限时:同时拥有多个权限资源时,数字越大权限优先级越高。)"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24" v-show="model.category != 1">
            <el-form-item
              :label="model.category != 2 ? '链接页面：' : '接口地址：'"
              prop="model.navigateUrl"
            >
              <el-input
                v-model="model.navigateUrl"
                :placeholder="
                  model.category != 2
                    ? '请求的页面，项目里的页面，如：/admin/sysUser/list'
                    : '请求的接口地址，如：/admin/sysUser/query'
                "
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item prop="model.layout">
              <span slot="label">
                <el-tooltip
                  content="布局容器，不设置默认取框架的。如需额外设置，请在 MenuLayout 字典类型中添加对应的容器。"
                  placement="top"
                >
                  <i class="el-icon-question"></i>
                </el-tooltip>
                布局容器：
              </span>
              <el-select
                v-model="model.layout"
                placeholder="布局容器，不设置默认取框架的"
                clearable
              >
                <el-option
                  v-for="item in controlData.layoutOptions"
                  :key="item.code"
                  :label="item.name"
                  :value="item.code"
                ></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <!-- <el-row v-show="model.category == 0 || model.category == 3">
          <el-col :span="24">
            <el-form-item label="页面路由：" prop="model.route">
              <el-input v-model="model.route" placeholder="前后端分离必填，外部链接请填写完整url，页面按钮不填"></el-input>
            </el-form-item>
          </el-col>
        </el-row>-->
        <el-row v-show="model.category == 0 || model.category == 3">
          <el-col :span="12">
            <el-form-item label="资源图标：" prop="model.icon">
              <el-input
                v-model="model.icon"
                placeholder="font awesome 图标"
              ></el-input>
            </el-form-item>
            <!-- <el-form-item label="资源图标：" prop="model.icon">
              <el-popover
                placement="bottom-start"
                width="460"
                trigger="click"
                @show="$refs['iconSelect'].reset()"
              >
                <IconSelect ref="iconSelect" @selected="($event) => { model.icon = $event; }" />
                <el-input slot="reference" v-model="model.icon" placeholder="点击选择图标" readonly>
                  <svg-icon
                    v-if="model.icon"
                    slot="prefix"
                    :icon-class="model.icon"
                    class="el-input__icon"
                    style="height: 32px;width: 16px;"
                  />
                  <i v-else slot="prefix" class="el-icon-search el-input__icon" />
                </el-input>
              </el-popover>
            </el-form-item>-->
          </el-col>
          <el-col :span="12">
            <el-form-item label="打开目标：" prop="model.target">
              <!-- <el-input v-model="model.target" placeholder="外部链接填：_blank"></el-input> -->
              <el-select v-model="model.target">
                <el-option
                  value="mainframe"
                  label="当前页面（默认）"
                ></el-option>
                <el-option value="_blank" label="新标签页"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item label="是否启用：" prop="model.isEnabled">
              <el-radio v-model="model.isEnabled" :label="true">是</el-radio>
              <el-radio v-model="model.isEnabled" :label="false">否</el-radio>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="权限控制：" prop="model.isUnderControl">
              <el-radio v-model="model.isUnderControl" :label="true"
                >是</el-radio
              >
              <el-radio v-model="model.isUnderControl" :label="false"
                >否</el-radio
              >
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="12">
            <el-form-item prop="model.isVisible">
              <span slot="label">
                <el-tooltip
                  content="选择隐藏则路由将不会出现在侧边栏，但仍然可以访问"
                  placement="top"
                >
                  <i class="el-icon-question"></i> </el-tooltip
                >显示状态：
              </span>
              <el-radio v-model="model.isVisible" :label="true">是</el-radio>
              <el-radio v-model="model.isVisible" :label="false">否</el-radio>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item prop="model.isCache">
              <span slot="label">
                <el-tooltip
                  content="'keep-alive'缓存是根据组件'name'进行匹配的.如果不需要缓存,需要设置组件'name',这个'name'与路由'name'要保持一致"
                  placement="top"
                >
                  <i class="el-icon-question"></i> </el-tooltip
                >是否缓存：
              </span>
              <el-radio v-model="model.isCache" :label="true">是</el-radio>
              <el-radio v-model="model.isCache" :label="false">否</el-radio>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row v-show="model.category == 2">
          <el-col :span="24">
            <el-form-item label="数据权限表达式：" prop="model.dataExpression">
              <el-input
                type="textarea"
                v-model="model.dataExpression"
                :autosize="{ minRows: 5, maxRows: 20 }"
                placeholder="如：create_user_id = '{user.userId}'，默认提供的变量请看后台qm-common里的DataExprParseService.java"
              ></el-input>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row>
          <el-col :span="24">
            <el-form-item label="备注" prop="model.description">
              <el-input type="textarea" v-model="model.description"></el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </template>
    </qm-table>

    <el-dialog title="查看分配角色" :visible.sync="dialogRoleVisible" @closed="dialogRoleClose">
      <el-row>
        <el-col :span="6">
          <el-select
            v-model="searchRoles"
            value-key="value"
            multiple
            filterable
            remote
            placeholder="请输入关键词"
            :remote-method="remoteMethod"
          >
            <el-option v-for="item in roles" :key="item.value" :label="item.label" :value="item"></el-option>
          </el-select>
        </el-col>
        <el-col :span="3" :offset="1">
          <el-button type="primary" @click="addNewRole" icon="el-icon-plus">添加</el-button>
        </el-col>
      </el-row>
      <qm-table
        ref="roleTable"
        v-if="dialogRoleVisible"
        :urls="{ query: { url:'/admin/sysMenu/setRoles/getRoles',method: 'get'}}"
        :beforeQuery="beforeQuery"
        :showView="false"
        :showEdit="false"
        :showDelete="false"
      >
        <qm-table-column field="NAME" >角色名称</qm-table-column>
        <qm-table-column field="CODE" >角色编码</qm-table-column>
        <template v-slot:moreBtn="{ row }">
          <el-button @click="move(row)">移除</el-button>
        </template>
      </qm-table>
    </el-dialog>
  </div>

</template>

<script>
import Controller from "@/libs/framework/controller";
import request from "@/utils/request";
import _ from "lodash";
import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css";
import IconSelect from "@/components/IconSelect";

export default class Instance extends Controller {
  onBeforeInit() {
    this.urls = {
      model: "/admin/sysMenu/getListModel",
      save: "/admin/sysMenu/save",
      delete: "/admin/sysMenu/delete",
      entity: "/admin/sysMenu/getEntity",
    };
    this.permissions = {
      add: "admin:sysMenu:add", // 新增
      view: "admin:sysMenu:view", // 查看
      edit: "admin:sysMenu:edit", // 编辑
      delete: "admin:sysMenu:delete", // 删除
    };
  }

  onAfterGetEntity(result) {
    const { models, pageAction } = result || {};
    const model = (models || {}).model;
    if (model && pageAction === "create") {
      result.models.model = _.extend({}, model, {
        parentId: this.vm.parentId || undefined,
        isEnabled: true,
        isUnderControl: true,
        isVisible: true,
        isCache: true,
      });
      this.vm.parentId = undefined;
    }
  }

  onBeforeSave(postModel) {
    if (postModel.pageAction === "create") {
      postModel.model.isDeleted = false;
    }
    if (postModel.model.parentId === undefined) {
      postModel.model.parentId = null;
    }
    return true;
  }

  mixin() {
    return {
      components: {
        Treeselect,
        IconSelect,
      },
      data() {
        return {
          modalVisible: false,
          dialogVisible: false,
          dialogRoleVisible: false,
          searchRoles:[],
          roles: [],
          row:{},
          parentId: "",
          menuData: [],
          treeData: [],
          rules: {
            model: {
              name: [
                {
                  required: true,
                  message: "请输入资源名称",
                  trigger: "blur",
                },
              ],
              category: [
                {
                  required: true,
                  message: "请选择资源类型",
                },
              ],
              isEnabled: [
                {
                  required: true,
                  message: "请选择是否启用",
                },
              ],
              isUnderControl: [
                {
                  required: true,
                  message: "请选择是否进行权限控制",
                },
              ],
              isCache: [
                {
                  required: true,
                  message: "请选择是否缓存路由",
                },
              ],
              isVisible: [
                {
                  required: true,
                  message: "请选择是否显示菜单栏",
                },
              ],
              // route: [
              //   {
              //     required: true,
              //     message: "请填写链接路由",
              //     trigger: 'blur'
              //   },
              // ]
            },
          },
        };
      },
      methods: {
        normalizer(node) {
          return {
            id: node.id,
            label: node.text,
            children: node.children,
          };
        },
        addSubMenu(row) {
          this.parentId = row.menuId;
          this.$refs["qmTable"].addNew();
        },
        addNewRole() {
          console.log(this.row)
          if (null == this.searchRoles || this.searchRoles.length == 0) {
            this.$message("请先选择授予的角色!");
            return;
          }
          request({
            url: "/admin/sysMenu/addMenuRoles",
            method: "post",
            data: {
              menuId: this.row.menuId,
              parentId: this.row.parentId,
              roles: this.searchRoles,
            },
          })
            .then((r) => {
              if (r && !r.initMessage) {
                this.$message({
                  message: "添加成功",
                  type: "success",
                });
                this.refreshMenuRole();
              } else {
                reject(r.initMessage || "数据请求失败");
              }
            })
            .catch((e) => {
              reject(e);
            });
        },
        move(row) {
          console.log("remove")
          this.$confirm("确定要移除么？", "提示", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
          })
            .then(() => {
              request({
                url: "/admin/sysMenu/removeRole",
                method: "post",
                params: {
                  menuId: this.row.menuId,
                  roleId: row.ROLE_ID,
                },
              })
                .then((r) => {
                  if (r && !r.initMessage) {
                    this.$message({
                      message: "删除成功",
                      type: "success",
                    });
                    this.refreshMenuRole();
                  } else {
                    reject(r.initMessage || "数据请求失败");
                  }
                })
                .catch((e) => {
                  reject(e);
                });
            })
            .catch(() => {
              this.$message({
                type: "info",
                message: "已取消删除",
              });
            });
        },
        refreshMenuRole(){
          this.$refs["roleTable"].refresh();
          this.searchRoles = [];
          this.remoteMethod();
        },
        setRoles(row){
          this.row = row;
          this.remoteMethod();
          this.dialogRoleVisible = true;
        },
        beforeQuery(parmas) {
          parmas.query.term = this.row.menuId;
        },
        dialogRoleClose() {
          this.dialogRoleVisible = false;
          this.searchRoles = [];
          this.roles = [];
          this.row = {};
        },
        remoteMethod(query) {
          request({
            url: "/admin/sysMenu/setRoles/selectRoles",
            method: "get",
            params: { term: query ,menuId: this.row.menuId},
          })
            .then((r) => {
              if (r) {
                this.roles = r.map((m) => {
                  return {
                    value: m.roleId,
                    label: m.name,
                    roleId: m.roleId,
                  };
                });
              } else {
                reject("数据请求失败");
              }
            })
            .catch((e) => {
              reject(e);
            });
        },

        removeRow(rows) {
          let row = rows && rows.length ? rows[0] : {};
          let parent = this.$refs["qmTable"].getRowById(row.parentId);
          const menuId = row.menuId;
          const url = this.urls.delete || this.urls.remove;

          if (url === undefined || menuId === undefined) {
            this.$message({
              showClose: true,
              message: "PostModel或者URL不可为undefined",
              type: "error",
            });
          } else {
            this.$confirm("删除会一并删除权限数据，是否继续删除？", "提示", {
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
            })
              .then(() => {
                let loading = this.appLoading("正在删除...");
                request({
                  url: url,
                  method: "post",
                  data: {
                    delete: JSON.stringify([{ menuId: menuId }]),
                  },
                })
                  .then((res) => {
                    if (res && res.success) {
                      this.$message({
                        showClose: true,
                        message: res.message || "删除成功！",
                        type: "success",
                      });
                      // 从数据源删除该行即可，不需要重新加载整棵树
                      if (parent && parent.children) {
                        parent.children.remove(row);
                      } else {
                        // 删除的是顶级的菜单
                        this.menuData.remove(row);
                      }
                    } else {
                      this.$message({
                        showClose: true,
                        message: res ? res.message : undefined || "删除失败！",
                        type: "error",
                      });
                    }
                  })
                  .catch((err) => {
                    this.$message({
                      showClose: true,
                      message: err.message || "删除失败！",
                      type: "error",
                    });
                  })
                  .finally(() => {
                    loading.close();
                  });
              })
              .catch();
          }
        },
        treeRefresh(params) {
          this.getAllTreeData();
        },
        getAllTreeData() {
          request({
            url: "/admin/sysMenu/getAllMenuData",
            method: "post",
            params: {},
          })
            .then((r) => {
              if (r && r.parameters && r.parameters.treeData) {
                this.menuData = this.handleTree(r.parameters.treeData);
              }
            })
            .catch((e) => {
              this.msgError("获取数据失败，请稍后再试");
            });
        },
        handleTree(treeData) {
          let arr = [];
          _.each(treeData, (item) => {
            let m = {};
            m.id = item.id;
            m.menuId = item.id;
            m.code = item.data.code;
            m.isEnabled = item.data.isEnabled;
            m.navigateUrl = item.data.navigateUrl;
            m.route = item.data.route;
            m.text = item.text;
            m.type = item.type;
            m.parentId = item.data.parentId;
            if (item.children && item.children.length) {
              m.children = this.handleTree(item.children) || [];
            } else {
              m.children = [];
            }
            arr.push(m);
          });
          return arr;
        },
        getInitTreeData() {
          request({
            url: "/admin/sysMenu/getChild",
            method: "get",
            params: {},
          })
            .then((r) => {
              if (r && r.length) {
                r.forEach((item) => {
                  if (item.children) {
                    item.childs = [];
                  }
                  if (item.id !== "root") {
                    item.menuId = item.id;
                  }
                });
                this.treeData = [];
                this.treeData.push(...r);
              }
            })
            .catch((e) => {
              this.msgError("获取数据失败，请稍后再试");
            });
        },
        loadChildrenMethod({ row }) {
          // 异步加载子节点
          return new Promise((resolve) => {
            request({
              url: "/admin/sysMenu/getChild",
              method: "get",
              params: { id: row.id },
            })
              .then((r) => {
                r.forEach((item) => {
                  if (item.children) {
                    item.childs = [];
                  }
                  if (item.id !== "root") {
                    item.menuId = item.id;
                  }
                });
                resolve(r);
              })
              .catch((e) => {
                this.msgError("获取数据失败，请稍后再试");
              });
          });
        },
      },
      created() {
        // this.getInitTreeData();
        this.getAllTreeData();
      },
    };
  }
}
</script>

<style scoped lang="scss"></style>
